/*
 * main.cpp
 *
 *  Created on: Jun 18, 2013
 *      Author: dsweeney
 */
#include "DLStypes.h"
#include "Node.h"
#include <stack>


#include <iostream>

void popIfNotEmpty(std::stack<Node*>* path);

///////////////////////////////////////////////////////////////////////////////
	bool** randomizeEnvironment()
	{
		bool** environment = new bool*[x];

		for(unsigned int i = 0; i < x; i++)
			environment[i] = new bool[y];


		srand(time(NULL));

		for(unsigned int i = 0; i < x; i++)
		{
			for(unsigned int j = 0; j < y; j++)
			{
				environment[i][j] = rand() & 0x1;
				//environment[i][j] = DIRTY;
			}
		}
		return environment;
	}
///////////////////////////////////////////////////////////////////////////////
	bool goalTest (bool* state [])
	{
		bool returnVal = CLEAN;

		for(unsigned int i = 0; (i < x)&&(returnVal == CLEAN); i++)
		{
			for(unsigned int j = 0; (j < y)&&(returnVal == CLEAN); j++)
				returnVal = state[i][j];
		}
		//return returnVal;
		return false;
	}
///////////////////////////////////////////////////////////////////////////////
	result_e recursiveDLS (Node* n, int limit, std::stack<Node*>* path)
	{
		path->push(n);

		if(goalTest(n->getState()))
		{
			std::cout<<"GOAL STATE"<<std::endl;
			std::cout<<"Total search cost = "<<n->getId()<<std::endl;
			n->printState();
			return GOAL;
		}
		else if (limit == 0)
		{
			popIfNotEmpty(path);
			return CUTOFF;
		}
		else
		{
			bool cutoffOccurred = false;
			Node* child;
			while((child = n->getNextChild()) != NULL)
			{
				result_e result = recursiveDLS(child, limit - 1, path);

				switch(result)
				{
				case CUTOFF:
					//if we pop here will trying to access free'd memory
					cutoffOccurred = true;
					break;
				case FAILURE:
					popIfNotEmpty(path);
					break;
				default:
					return result;
				}
			}

			if(cutoffOccurred)
			{
				popIfNotEmpty(path);
				return CUTOFF;
			}
			else
			{
				popIfNotEmpty(path);
				return FAILURE;
			}
		}
	}
///////////////////////////////////////////////////////////////////////////////
	void popIfNotEmpty (std::stack<Node*>* path/*, Node* n*/)
	{
		if(!path->empty())
		{
			Node* n = path->top();
			path->pop();
			delete n;
		}
		else
			std::cout<<"**** tried popping from empty stack ****"<<std::endl;
	}
///////////////////////////////////////////////////////////////////////////////
int main (void)
{
	bool** initialState = randomizeEnvironment();
	Node* n = new Node(INITIAL_STATE, initialState, 0, 0);
	std::stack <Node*> path;

	recursiveDLS(n, limit, &path);

	//dont need to count the initial state.
	if(path.size() != 0)
		std::cout<<"path length = "<<path.size()-1<<std::endl;
	else
		std::cout<<"path length = "<<path.size()<<std::endl;

	while(!path.empty())
	{
		switch(path.top()->getAction())
		{
		case INITIAL_STATE:
			std::cout<<"INITIAL_STATE ";
			break;
		case SUCK:
			std::cout<<"SUCK ";
			break;
		case NORTH:
			std::cout<<"NORTH ";
			break;
		case EAST:
			std::cout<<"EAST ";
			break;
		case SOUTH:
			std::cout<<"SOUTH ";
			break;
		case WEST:
			std::cout<<"WEST ";
			break;
		default:
			std::cout<<"something went horribly wrong!"<<std::endl;
		};
		std::cout<<"Node ID = "<<path.top()->getId()<<std::endl;
		popIfNotEmpty(&path);
	}

	return 1;
}


